﻿Imports System.Data
Imports System.Configuration
Imports System.Linq
Imports System.Web
Imports System.Web.Security
Imports System.Web.UI
Imports System.Web.UI.HtmlControls
Imports System.Web.UI.WebControls
Imports System.Web.UI.WebControls.WebParts
Imports System.Xml.Linq
Imports System.IO
Imports System.IO.Compression

''' <summary>
''' Summary description for PersistViewStateToFileSystem
''' </summary>
Public Class PersistViewStateToFileSystem
    Inherits Page
    '
    ' TODO: Add constructor logic here
    '
    Public Sub New()
    End Sub
    Protected Overrides Sub SavePageStateToPersistenceMedium(state As Object)
        Dim los As New LosFormatter()
        Dim sw As New StringWriter()
        los.Serialize(sw, state)

        Dim w As StreamWriter = File.CreateText(ViewStateFilePath)
        w.Write(sw.ToString())
        w.Close()
        sw.Close()

    End Sub

    Protected Overrides Function LoadPageStateFromPersistenceMedium() As Object
        ' determine the file to access
        If Not File.Exists(ViewStateFilePath) Then
            Return Nothing
        Else
            ' open the file
            Dim sr As StreamReader = File.OpenText(ViewStateFilePath)
            Dim viewStateString As String = sr.ReadToEnd()
            sr.Close()

            ' deserialize the string
            Dim los As New LosFormatter()
            Return los.Deserialize(viewStateString)
        End If
    End Function


    Public ReadOnly Property ViewStateFilePath() As String

        Get
            Dim isSessionId As Boolean = Convert.ToBoolean(System.Configuration.ConfigurationManager.AppSettings("isSessionId"))
            Dim folderName As String = Path.Combine(Request.PhysicalApplicationPath, "PersistedViewState")
            Dim fileName As String = String.Empty
            Dim filepath As String = String.Empty
            If Not isSessionId Then
                Dim hfVSFileName As HiddenField = Nothing
                Dim VSFileName As String = ""

                ' Get the HiddenField Key from the page
                hfVSFileName = TryCast(FindControl(Me, "hfVSFileName"), HiddenField)

                ' Get the HiddenField value from the page
                Dim hfVSFileNameVal As String = GetValue(hfVSFileName.UniqueID.ToString())
                If Not String.IsNullOrEmpty(hfVSFileNameVal) Then
                    VSFileName = hfVSFileNameVal
                End If

                If Not Page.IsPostBack Then
                    VSFileName = GenerateGUID()
                    hfVSFileName.Value = VSFileName

                    'Removing files from Server
                    RemoveFilesfromServer()
                End If

                fileName = VSFileName & "-" & Path.GetFileNameWithoutExtension(Request.Path).Replace("/", "-") & ".vs"
                filepath = Path.Combine(folderName, fileName)

                Return filepath
            Else
                If Session("viewstateFilPath") Is Nothing Then

                    fileName = Session.SessionID & "-" & Path.GetFileNameWithoutExtension(Request.Path).Replace("/", "-") & ".vs"
                    filepath = Path.Combine(folderName, fileName)
                    Session("viewstateFilPath") = filepath
                End If
                Return Session("viewstateFilPath").ToString()
            End If
        End Get
    End Property

    Public Overloads Shared Function FindControl(root As Control, controlId As String) As Control
        If root.ID = controlId Then
            Return root
        End If

        For Each c As Control In root.Controls
            Dim t As Control = FindControl(c, controlId)
            If t IsNot Nothing Then
                Return t
            End If
        Next

        Return Nothing
    End Function
    Public Function GetValue(uniqueId As String) As String
        Return System.Web.HttpContext.Current.Request.Form(uniqueId)
    End Function

    Private Sub RemoveFilesfromServer()
        Try
            Dim folderName As String = Path.Combine(Request.PhysicalApplicationPath, "PersistedViewState")
            Dim _Directory As New DirectoryInfo(folderName)
            Dim files As FileInfo() = _Directory.GetFiles()
            Dim threshold As DateTime = DateTime.Now.AddMinutes(-15)
            For Each file As FileInfo In files
                If file.CreationTime <= threshold Then
                    file.Delete()
                End If
            Next
        Catch ex As Exception

        End Try
    End Sub
    ''' <summary>
    ''' A GUID is created to store the file names
    ''' </summary>
    Private Function GenerateGUID() As String
        Return System.Guid.NewGuid().ToString("")
    End Function

End Class
